/**
 * 微信支付回调服务
 */
import { Builder, parseString, convertableToString, OptionsV2 } from 'xml2js';
import { ICommonParams } from '@feidao/service/interfaces';
import log from '@feidao/web/atom/nodejs/logger/log';

interface IXmlJson {
	xml: IWxMsg;
}

interface IWxMsg {
	return_code: string; // 返回状态码	必填	描述：SUCCESS/FAIL
	return_msg: string; // 返回信息 必填	描述：OK	当return_code为FAIL时返回信息为错误原因 ，例如	签名失败 参数格式校验错误
	attach: string; // 附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
	// 以下字段在return_code为SUCCESS的时候有返回
	appid: string; // 公众账号ID 必填 描述：调用接口提交的公众账号ID
	mch_id: string;// 商户号 必填 描述：调用接口提交的商户号
	device_info: string;// 设备号 非必填 描述：自定义参数，可以为请求支付的终端设备号等
	nonce_str: string;// 随机字符串	 必填 描述：微信返回的随机字符串
	openid: string;// 公众账号ID 必填 描述：调用接口提交的公众账号ID
	sign: string;// 签名 必填 描述：微信返回的签名值，详见签名算法
	result_code: string;// 业务结果	 必填 描述：SUCCESS/FAIL
	err_code: string;// 错误代码	 非必填 描述：当result_code为FAIL时返回错误代码，详细参见下文错误列表
	err_code_des: string;// 错误代码描述	 非必填 描述：当result_code为FAIL时返回错误描述，详细参见下文错误列表
	// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
	trade_type: string;// 交易类型	 必填 描述：JSAPI 公众号支付	NATIVE 扫码支付	APP APP支付	说明详见参数规定
	prepay_id: string;// 预支付交易会话标识 必填 描述：微信生成的预支付会话标识，用于后续接口调用中使用，该值有效期为2小时
	code_url: string;// 二维码链接 非必填 描述：trade_type为NATIVE时有返回，用于生成二维码，展示给用户进行扫码支付
}

/**
 * 将xml转为json
 * @param xml_str
 * @param options
 */
function xml2json(xml_str: convertableToString, options: OptionsV2) {
	return new Promise<IXmlJson>((resolve, reject) => {
		parseString(xml_str, options, (err, result) => {
			if (err) {
				const err_msg = (err && err.toString()) || 'unknow';
				log(`parse xml:${xml_str}.error msg: ${err_msg}`);
				reject(err_msg);
			} else {
				resolve(result);
			}
		});
	});
}

/**
 * 将json转为xml
 * @param obj
 * @param options
 */
function json2xml(obj: any, options: OptionsV2) {
	const builder = new Builder(options);
	const xml_result = builder.buildObject(obj);
	return xml_result;
}

// 支付处理
async function pay_process(xml: IXmlJson, _spaceid: string) {
	// todo 做支付处理
}

export default async function atom(msg: ICommonParams, action_id: string, session_id: string, _spaceid: string) {
	log('coming params is --:');
	log(JSON.stringify(msg));

	const params = msg.data;
	log('receive msg from wx:');
	log(JSON.stringify(params));
	try {
		log('xml to json start');
		const data = await xml2json(params, { explicitArray: false });
		log(`xml to json end --data = ${JSON.stringify(data)}`);
		const attach = JSON.parse(data.xml.attach);
		const spaceid = params.spaceid || attach.spaceid || _spaceid;
		// 逻辑处理
		pay_process(data, spaceid);
		log(`get pay attach data, attach = ${JSON.stringify(attach)}`);
		return { data: '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>' };
	} catch (err) {
		const err_msg = (err && err.toString()) || 'unknow';
		log(`微信回调执行异常！${err_msg}`);
		return { data: '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[' + err_msg + ']]></return_msg></xml>' };
	}
}
